-- Libs
local md5 = require("md5")	
local http = require("socket.http")
http.USERAGENT = "WoWI Mod Uploader r" .. (string.match("$Revision: 4 $", "%d+") or 1)

-- Helper functions
local function split(char, text)
	local list = {}
	local pos = 1
	if( string.find("", char, 1) ) then
		error("Cannot break an empty string")
	end
	
	while(true) do
		local start, finish = string.find(text, char, pos)
		
		if( start ) then
			table.insert(list, string.sub(text, pos, start - 1))
			pos = finish + 1
		else
			table.insert(list, string.sub(text, pos))
			break
		end
	end
	return list
end

-- Link
local url = "http://www.wowinterface.com/downloads/editfile_xml.php"
local authURL
local mods = {}
local username
local password

--[[
100, The file id is missing.
101, You are not the owner of this file.
102, Password is not correct.
103, Username is not correct.
104, User does not have any addons in our database.
]]
local function testLogin()
	local page, response, headers = http.request(url .. "?l=" .. username .. "&p=" .. password .."&do=listfiles")
	
	if( page ) then
		if( string.match(page, "<interface_list>(.+)</interface_list>") ) then
			authURL = url .. "?l=" .. username .. "&p=" .. password;
			
			-- Parse the list of mods, will need it eventually
			local data = {}
			for i, row in pairs(split("\n", page)) do
				local field, txt = string.match(row, "<(.+)>(.+)<(.+)")

				if( string.match(row, "</item>" ) ) then
					table.insert(mods, data)
					data = {}
				elseif( field and txt ) then
					data[field] = txt
				end
			end
		
			return true
		else
			local errorMsg = string.match(page, "<message>(.+)</message>")
			if( errorMsg ) then
				return nil, errorMsg
			else
				return nil, "Cannot parse error message."
			end
		end
	else
		return nil, response
	end
	
	return nil
end

-- Actual script
local function updateMod(wrapLog)
	local page = [=[
	<?xml version="1.0" encoding="ISO-8859-1"?>
		<interface_edit>
			<id>5293</id>
			<title>SSBattleground Reformat</title>
			<version>2.0.2</version>
			<size>9372</size>
			<description><![CDATA[SSBGReformat is aimed at cleaning up the battleground interface from the changes made for cross server battlegrounds.
	
	[b]Features[/b]
	 - Abbreviated server names, Icecrown will become IC.
	 - Remove server name from chat, will display * next to there name if they are from a different server
	 - Remove system message spam (so and so has joined the raid group and so and so has left the raid group ) inside a battleground
	 - Auto append server name, if you're trying to message Foo from the Bar server you can just type /w Foo test and it'll automatically append '-Bar' as long as two people don't share the name
	
	Type /ssformat to pull up the configuration, can also be used with SSPVP for a configuration UI.
	
	Thanks Wahnfried from EU-Alleria for the German localization.
	
	This is a load on demand addon and will not be loaded until you enter Arathi Basin, Alterac Valley or Warsong Gulch.
	[code]test[/code]
	]]></description>
	</interface_edit>]=]
	
	if( page ) then
		local version = string.match(page, "<version>(.+)</version>")
		local description = string.match(page, "<description>(.+)</description>")
	
		return true
	else
		return nil, response
	end
	
	return nil, nil
end

local valid = {"-u", "-p", "-hp", "-ver", "-log", "-desc-log", "-svn", "-zip", "-fid", "-list"}
local function isValidCommand(check)
	for _, cmd in pairs(valid) do
		if( cmd == check ) then
			return true
		end
	end
	
	return nil
end

local function showHelp(msg)
	if( msg ) then
		print(msg)
	end
	
	print("-u <username>       Username to use when logging in")
	print("-p <password>       Password to use when logging in")
	print("-hp <md5hash>       MD5 hash of your password instead of plain text")
	print("-list               List all of your uploaded mods by id, title and last updated")
	print("-ver <version>      File version to use for updating")
	print("-log \"<args>\"       Arguments to pass to svn log for creating the changelog.txt file")
	print("-desc-log \"<args>\"  Same as above, except for the mod description change log")
	print("-svn \"<path>\"       Path to the SVN repository of the addon being uploaded")
	print("-zip \"<path>\"       Path to the ZIP program for zipping the addon folder")
	print("-fid <fid>          File ID to update, see -list to get the ID")
end

local args = {}
-- Quick parse of the arguments
if( #(arg) > 0 ) then
	-- Quick scan, is help there?
	for _, cmd in pairs(arg) do
		if( cmd == "-h" or cmd == "--help" ) then
			showHelp()
			return
		end
	end

	-- Nope
	for i=1, #(arg) do
		local cmd = arg[i]
		if( cmd ) then
			local next = arg[i + 1]
			local nextValid = isValidCommand(nextValid)

			-- Make sure it's a good arg
			if( not isValidCommand(cmd) ) then
				showHelp("Invalid argument used \"" .. cmd .. "\"")
				return
			end

			-- eg, -p <foo>
			if( next and not nextValid ) then
				args[string.sub(cmd, 2)] = next
				arg[i + 1] = nil

			-- eg, -svn
			elseif( not next or nextValid ) then
				args[string.sub(cmd, 2)] = true
			end
		end
	end
end

-- Figure out whats up
if( args["u"] ) then
	username = args["u"]
end

if( args["p"] ) then
	password = md5.sumhexa(args["p"])
	args["p"] = nil
end

if( args["hp"] ) then
	password = args["hp"]
	args["hp"] = nil
end

-- Check/ask for login info
-- 3 attempts and then exit
for i=1, 3 do
	if( not username ) then
		io.write("Username: ")
		username = io.read()
	end
	
	if( not password ) then
		io.write("Password: ")
		password = md5.sumhexa(io.read())
	end

	print("Logging into WoWInterface...")
	
	local response, msg = testLogin()
	if( response ) then
		print("Welcome " .. username .. ", login successful.")
		break
	end
	
	print("Error loggging in, " .. msg)
	username = nil
	password = nil
	
	if( i == 3 ) then
		print("Maximum number of retries used.")		
		return
	end
end

-- List addons
if( args["list"] ) then
	-- id, version, title, size
	table.sort(mods, function(a, b)
		if( not b ) then return false end
		return ( a.id > b.id )
	end)
	
	for _, mod in pairs(mods) do
		print("[" .. mod.id .. "] " .. mod.title .. " (" .. mod.version .. ")")
	end
	
	return
end

-- Find the fileID
local function findMod(find, key)
	find = string.lower(find)
	for _, mod in pairs(mods) do
		if( string.lower(mod[key]) == find ) then
			return mod.id
		end
	end
	
	return nil
end

local fid
if( args["fid"] ) then
	fid = findMod(args["fid"], "id")
	if( not fid ) then
		print("Cannot find any mods with the file id of \"" .. args["fid"] .. "\"")
	end
end

if( args["ftitle"] ) then
	fid = findMod(args["ftitle"], "title")
	if( not fid ) then
		print("Canot find any mods that match the title \"" .. args["ftitle"] .. "\"")
	end
end

--[[
if( args["ftoc"] ) then
	--## Title: Loot Modifier
	
	
	if( not fid ) then
		print("Cannot find any mods that match the TOC title \"" .. args["ftoc"] .. "\"")
	end
end
]]

-- Still nothing found, ask for it manually
if( not fid ) then
	while( true ) do
		io.write("File ID: ")
		fid = tonumber(io.read())
		
		if( fid ) then
			-- Make sure it's actually one of ours
			if( findMod(fid, "id") ) then
				break
			else
				print("Cannot find any mods with the file id \"" .. fid .. "\"")
			end
		else
			print("Invalid ID entered, must be a number.")
		end
	end
end

-- All of the actual updating things should go here now